#include "NotificationManager.h"
#include <iostream>

using namespace std;


NotificationManager* NotificationManager::g_pkInstance = NULL;

NotificationManager *NotificationManager::GetInstance()
{
	if (!g_pkInstance)
	{
		g_pkInstance = new NotificationManager();
	}

	return g_pkInstance;
}


NotificationManager::NotificationManager(void)
:
m_pkSemaphore(new Poco::Semaphore(MAX_AMOUNT_OF_THREADS))
{
	
}

NotificationManager::~NotificationManager(void)
{
}


void NotificationManager::AddNotification(Notification *notif)
{
	Notification *queuedNotif = m_qNotificationQueue.front();

	if (queuedNotif)
	{
		Poco::Thread *freeThread = LookForFreeThread();
		if (freeThread)
		{
			freeThread->start(*queuedNotif);
			m_qNotificationQueue.pop();
		}
		else
		{
			m_qNotificationQueue.push(notif);
		}

		return;
	}
	else
	{
		Poco::Thread *freeThread = LookForFreeThread();
		if (freeThread)
		{
			freeThread->start(*notif);
		}
		else
		{
			m_qNotificationQueue.push(notif);
		}
	}

	
}


Poco::Thread *NotificationManager::LookForFreeThread() 
{
	vector<Poco::Thread*>::iterator it = m_vtrThreads.begin();
	while(it != m_vtrThreads.end())
	{
		if (!(*it)->isRunning())
		{
			return (*it);
		}
		it++;
	}

	return NULL;
}

void NotificationManager::InitMgr()
{
	cout<<"MANAGER START"<<endl;

	for (int i = 0; i < MAX_AMOUNT_OF_THREADS; i++)
	{
		Poco::Thread *thread = new Poco::Thread();
		m_vtrThreads.push_back(thread);
	}
}

void NotificationManager::run()
{
	cout<<"MANAGER RUN"<<endl;
	InitMgr();

	
	Notification *queuedNotif = m_qNotificationQueue.front();
	while(queuedNotif)
	{
		cout<<"THREAD IS ALIVE"<<endl;
		Poco::Thread *freeThread = LookForFreeThread();
		if (freeThread)
		{	
			freeThread->start(*queuedNotif);
			m_qNotificationQueue.pop();
			m_pkSemaphore->wait();
		}
	}

}

